package com.alibaba.citrus.ots.platform.enhance.facade.service;

import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.exception.FunctionException;
import com.alibaba.citrus.ots.common.util.DateUtils;
import com.alibaba.citrus.ots.platform.enhance.functions.constants.StrategyConstants;
import com.alibaba.citrus.ots.platform.enhance.functions.strategy.entity.StrategyEntity;
import com.alibaba.citrus.ots.platform.enhance.functions.strategy.factory.StrategyFactory;
import com.alibaba.citrus.ots.platform.enhance.functions.utils.ConverterUtils;
import com.alibaba.citrus.ots.platform.enhance.repository.DimensionQueryRepository;
import com.alibaba.citrus.ots.platform.enhance.repository.DimensionWriteRepository;
import com.alibaba.citrus.ots.platform.enhance.repository.StrategyQueryRepository;
import com.alibaba.citrus.ots.platform.enhance.repository.StrategyWriteRepository;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.model.dto.SearchReqDTO;
import com.epoch.app.bcots.model.dto.SearchScItemRequest;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.otsplatformenhance.api.dimensionwrite.service.DimensionWriteService;
import com.epoch.app.otsplatformenhance.api.strategywrite.service.StrategyWriteService;
import com.epoch.app.otsplatformenhance.dimension.dto.QueryListByPriorityRequest;
import com.epoch.app.otsplatformenhance.dimension.model.Dimension;
import com.epoch.app.otsplatformenhance.enums.DimensionTypeEnum;
import com.epoch.app.otsplatformenhance.enums.StrategyTypeEnum;
import com.epoch.app.otsplatformenhance.model.dto.*;
import com.epoch.app.otsplatformenhance.model.enums.RuleTypeEnum;
import com.epoch.app.otsplatformenhance.model.enums.StatusEnum;
import com.epoch.app.otsplatformenhance.model.enums.StrategyStatusEnum;
import com.epoch.app.otsplatformenhance.sdo.DimensionSDO;
import com.epoch.app.otsplatformenhance.sdo.StrategySDO;
import com.epoch.app.otsplatformenhance.strategy.dto.LoadStrategyRequest;
import com.epoch.app.otsplatformenhance.strategy.model.Strategy;
import com.epoch.app.otsplatformenhance.strategy.service.StrategyService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class StrategyWriteServiceImpl implements StrategyWriteService {
    @Resource
    private DimensionWriteRepository dimensionWriteRepository;

    @Resource
    private StrategyWriteRepository strategyWriteRepository;

    @Resource
    private DimensionWriteService dimensionWriteService;

    @Resource
    private StrategyQueryRepository strategyQueryRepository;

    @Resource
    private DimensionQueryRepository dimensionQueryRepository;

    @Resource
    private StrategyService strategyService;

    @Override
    @FacadeInvoker
    public Result<StrategyWriteCreateResponse> createStrategy(StrategyWriteCreateRequest request) {
        StrategyEntity strategyEntity = StrategyFactory.createStrategy(request);
        String id = strategyEntity.createAndUpdate();
        StrategyWriteCreateResponse response = new StrategyWriteCreateResponse();
        response.setId(id);
        return Result.success(response);
    }
    /**
     * 创建库存路由策略
     *
     * @param strategyInventoryRoutWriteCreateRequest
     * @return
     */
    @Override
    @FacadeInvoker
    @Transactional
    public Result<StrategyWriteCreateResponse> createInventoryRoutingStrategy(StrategyInventoryRoutWriteCreateRequest strategyInventoryRoutWriteCreateRequest) {
        /**
         * 保存主订单
         */
        //策略名称重复性校验
        StrategyLoadListRequest strategyLoadListRequest = new StrategyLoadListRequest();
        strategyLoadListRequest.setType(StrategyTypeEnum.INVENTORY_ROUTING.getCode());
        strategyLoadListRequest.setSize(1000);
        Result<List<Strategy>> listResult = strategyService.loadStrategyList(strategyLoadListRequest);
        List<Strategy> result = listResult.getResult();
        if (CollectionUtils.isNotEmpty(result)) {
            for (Strategy strategy : result) {
                if (StringUtils.isNotBlank(strategy.getName())) {
                    if (strategy.getName().equals(strategyInventoryRoutWriteCreateRequest.getName())) {
                        return Result.fail("999", "已存在相同策略名称无法创建");
                    }
                }
            }
        }
        //策略計算
        List<CalculatePriority> calculatePriority = strategyInventoryRoutWriteCreateRequest.getCalculatePriority();
        if (CollectionUtils.isNotEmpty(calculatePriority)) {
            Map<Object, Long> collect2 = calculatePriority.stream().collect(
                    Collectors.groupingBy(CalculatePriority::getPriority, Collectors.counting()));
            List<Object> collect3 = collect2.keySet().stream().
                    filter(key -> collect2.get(key) > 1).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect3)) {
                return Result.fail("999", "多种情况下策略计算优先级不能重复");
            }
        }
        StrategyWriteCreateResponse response = new StrategyWriteCreateResponse();
        StrategySDO strategySDO = new StrategySDO();
        if (StringUtils.isEmpty(strategyInventoryRoutWriteCreateRequest.getId())) {
            strategySDO.setName(strategyInventoryRoutWriteCreateRequest.getName());
            strategySDO.setPriority(strategyInventoryRoutWriteCreateRequest.getPriority());
            strategySDO.setDimensionType(strategyInventoryRoutWriteCreateRequest.getDimensionType());
            strategySDO.setType(StrategyTypeEnum.INVENTORY_ROUTING.getCode());
            strategySDO.setStatus(strategyInventoryRoutWriteCreateRequest.getStatus());
            Map<String, String> feature = new HashMap<>();
            feature.put(StrategyConstants.INVENTORY_ROUTING, JSONObject.toJSONString(strategyInventoryRoutWriteCreateRequest.getInventoryRoutingFeatureSDO()));
            feature.put(StrategyConstants.CALCULATE_PRIORITY, JSONObject.toJSONString(strategyInventoryRoutWriteCreateRequest.getCalculatePriority()));
            strategySDO.setFeature(feature);
            if (CollectionUtils.isNotEmpty(strategyInventoryRoutWriteCreateRequest.getStrategyValid())) {
                SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.DATETIME_FORMAT);
                try {
                    strategySDO.setValidBeginTime(sdf.parse(strategyInventoryRoutWriteCreateRequest.getStrategyValid().get(0)));
                    if (strategyInventoryRoutWriteCreateRequest.getStrategyValid().size() > 1 && null != strategyInventoryRoutWriteCreateRequest.getStrategyValid().get(1)) {
                        strategySDO.setValidEndTime(sdf.parse(strategyInventoryRoutWriteCreateRequest.getStrategyValid().get(1).substring(0, 10) + " 23:59:59"));
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }else {
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            StrategySDO strategySDO1 = new StrategySDO();
            strategySDO1.setId(strategyInventoryRoutWriteCreateRequest.getId());
            strategySDO1.setName(strategyInventoryRoutWriteCreateRequest.getName());
            strategySDO1.setPriority(strategyInventoryRoutWriteCreateRequest.getPriority());
            try {
                strategySDO1.setValidBeginTime(StringUtils.isNotBlank(strategyInventoryRoutWriteCreateRequest.getStrategyValid().get(0))?simpleDateFormat.parse(strategyInventoryRoutWriteCreateRequest.getStrategyValid().get(0)):null);
                strategySDO1.setValidEndTime(StringUtils.isNotBlank(strategyInventoryRoutWriteCreateRequest.getStrategyValid().get(1))?simpleDateFormat.parse(strategyInventoryRoutWriteCreateRequest.getStrategyValid().get(1)):null);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            strategyWriteRepository.modify(strategySDO1);
        }

        StrategySDO strategySDNew = ConverterUtils.createInventoryRoutingParams(strategyInventoryRoutWriteCreateRequest);
        String id = strategyWriteRepository.save(strategySDO);
        response.setId(id);
        if (CollectionUtils.isNotEmpty(strategySDNew.getDimensionSDOList())) {
            for (DimensionSDO dimensionSDO : strategySDNew.getDimensionSDOList()) {
                dimensionSDO.setStrategyId(response.getId());
                if (dimensionSDO.getId() == null) {
                    dimensionWriteRepository.create(dimensionSDO);
                } else {
                    dimensionWriteRepository.modify(dimensionSDO);
                }
            }
        }

        return Result.success(response);
    }
    @Override
    public  Result<Boolean> updateStatus(UpdateDimensionStatusRequest request) {
        StrategyQueryByIdRequest strategyQueryByIdRequest = new StrategyQueryByIdRequest();
        strategyQueryByIdRequest.setId(request.getId());
        Result<StrategyQueryByIdResponse> result = strategyQueryRepository.queryById(strategyQueryByIdRequest);
        StrategyQueryByIdResponse result1 = result.getResult();
        StrategySDO strategySDO = result1.getStrategySDO();
        if (Objects.nonNull(request.getStatusDesc())) {
            if (request.getStatusDesc()) {
                //主订单开启状态设置
                strategySDO.setStatus("1");
            } else {
                //主订单关闭状态设置
                strategySDO.setStatus("0");
            }
        }
        strategyWriteRepository.modify(strategySDO);
        return Result.success(true);
    }
    @Override
    @FacadeInvoker
    public Result<String> modifyInventoryRoutingStrategy(ModifyInventoryRoutingStrategyRequest modifyInventoryRoutingStrategyRequest) {
        /**
         * 修改主单
         */
        //获取策略主单id
        String strategyId = modifyInventoryRoutingStrategyRequest.getId();
        StrategyQueryByIdRequest request = new StrategyQueryByIdRequest();
        request.setId(strategyId);
        Result<StrategyQueryByIdResponse> result = strategyQueryRepository.queryById(request);
        StrategySDO strategySDO = result.getResult().getStrategySDO();
        strategySDO.setName(modifyInventoryRoutingStrategyRequest.getName());
        strategySDO.setPriority(modifyInventoryRoutingStrategyRequest.getPriority());
        strategySDO.setDimensionType(modifyInventoryRoutingStrategyRequest.getDimensionType());
        strategySDO.setType(modifyInventoryRoutingStrategyRequest.getType());
        strategySDO.setStatus(modifyInventoryRoutingStrategyRequest.getStatus());
        if (CollectionUtils.isNotEmpty(modifyInventoryRoutingStrategyRequest.getStrategyValid())) {
            SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.DATETIME_FORMAT);
            try {
                List<String> strategyValid = modifyInventoryRoutingStrategyRequest.getStrategyValid();
                strategySDO.setValidBeginTime(sdf.parse(strategyValid.get(0)));
                if (strategyValid.size() > 1 && null != strategyValid.get(1)) {
                    strategySDO.setValidEndTime(sdf.parse(strategyValid.get(1).substring(0, 10) + " 23:59:59"));
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        List<CalculatePriority> calculatePriority = modifyInventoryRoutingStrategyRequest.getCalculatePriority();
        if (CollectionUtils.isNotEmpty(calculatePriority)) {
            Map<Object, Long> collect2 = calculatePriority.stream().collect(
                    Collectors.groupingBy(CalculatePriority::getPriority, Collectors.counting()));
            List<Object> collect3 = collect2.keySet().stream().
                    filter(key -> collect2.get(key) > 1).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect3)) {
                return Result.fail("999", "多种情况下策略计算优先级不能重复");
            }
        }
        strategySDO.setStrategyValid(modifyInventoryRoutingStrategyRequest.getStrategyValid());
        Map<String, String> feature = strategySDO.getFeature();
        feature.put(StrategyConstants.INVENTORY_ROUTING, JSONObject.toJSONString(modifyInventoryRoutingStrategyRequest.getInventoryRoutingFeature()));
        feature.put(StrategyConstants.CALCULATE_PRIORITY, JSONObject.toJSONString(modifyInventoryRoutingStrategyRequest.getCalculatePriority()));
        strategySDO.setFeature(feature);
        /**
         * 修改策略子单
         */
        //根据前端传入的子单集合判断是删除还是修改
        List<DimensionSDO> scItemList = new ArrayList<>();
        List<DimensionSDO> wareHouseList = new ArrayList<>();
        List<DimensionSDO> dimensionList = new ArrayList<>();
        List<DimensionSDO> departmentList = new ArrayList<>();
        List<DimensionSDO> groupProductList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(strategySDO.getDimensionSDOList())) {
            strategySDO.getDimensionSDOList().forEach(dimensionSDO -> {
                if (DimensionTypeEnum.DEPARTMENT.getCode().equals(dimensionSDO.getCode())) {
                    departmentList.add(dimensionSDO);
                }
                if (DimensionTypeEnum.GOODS.getCode().equals(dimensionSDO.getCode())) {
                    scItemList.add(dimensionSDO);
                }
                if (DimensionTypeEnum.SALESMAN.getCode().equals(dimensionSDO.getCode())) {
                    dimensionList.add(dimensionSDO);
                }
                if (DimensionTypeEnum.CHANNEL.getCode().equals(dimensionSDO.getCode())) {
                    dimensionList.add(dimensionSDO);
                }
                if (DimensionTypeEnum.GROUPPRODUCT.getCode().equals(dimensionSDO.getCode())) {
                    groupProductList.add(dimensionSDO);
                }
                if (DimensionTypeEnum.STORE_ROOM.getCode().equals(dimensionSDO.getCode())) {
                    wareHouseList.add(dimensionSDO);
                }
            });
        }
        boolean isSuccess=true;
        //公司
        isSuccess=modifyDimensionConvertParams(DimensionTypeEnum.DEPARTMENT.getCode(), strategyId, departmentList, modifyInventoryRoutingStrategyRequest.getDepartmentList());
        if(!isSuccess){
            throw new FunctionException("OTS-04-001-00-15-043");
        }
        //货品
        isSuccess= modifyDimensionConvertParams(DimensionTypeEnum.GOODS.getCode(), strategyId, scItemList, modifyInventoryRoutingStrategyRequest.getScItemList());
        if(!isSuccess){
            throw new FunctionException("OTS-04-001-00-15-044");
        }
        //货品组
        isSuccess=modifyDimensionConvertParams(DimensionTypeEnum.GROUPPRODUCT.getCode(), strategyId, groupProductList, modifyInventoryRoutingStrategyRequest.getGroupProductList());
        if(!isSuccess){
            throw new FunctionException("OTS-04-001-00-15-045");
        }
        //仓库
        isSuccess=modifyDimensionConvertParams(DimensionTypeEnum.STORE_ROOM.getCode(), strategyId, wareHouseList, modifyInventoryRoutingStrategyRequest.getWareHouseList());
        if(!isSuccess){
            throw new FunctionException("OTS-04-001-00-15-046");
        }
        String strateGyId = strategyWriteRepository.modify(strategySDO);
        return Result.success(strateGyId);
    }
    private boolean modifyDimensionConvertParams(String code,String id,List<DimensionSDO> dimensionSDOListOld,List<DimensionSDO> dimensionSDOListNew) {
        //数据库中为空 前端传入有值为新增
        if (CollectionUtils.isEmpty(dimensionSDOListOld) && CollectionUtils.isNotEmpty(dimensionSDOListNew)) {
            for (DimensionSDO dimensionSDO : dimensionSDOListNew) {
                String valueName = dimensionSDO.getValueName();
                if (StringUtils.isNotBlank(valueName)) {
                    boolean contains = valueName.contains(":");
                    if (contains) {
                        dimensionSDO.setStrategyId(id);
                        dimensionSDO.setCode(code);
                        dimensionSDO.setValue(valueName.split(":")[1]);
                        dimensionSDO.setValueName(valueName.split(":")[0]);
                        dimensionWriteRepository.create(dimensionSDO);
                    }
                }
            }
        }
        //数据库中有值  前端为空则为删除
        if (CollectionUtils.isNotEmpty(dimensionSDOListOld) && CollectionUtils.isEmpty(dimensionSDOListNew)) {
            for (DimensionSDO dimensionSDO : dimensionSDOListOld) {
                dimensionSDO.setStrategyId(id);
                dimensionWriteRepository.delete(dimensionSDO);
            }
        }
        //数据库中有值  前端也传过来值  有可能是修改有可能是不变
        if (CollectionUtils.isNotEmpty(dimensionSDOListOld) && CollectionUtils.isNotEmpty(dimensionSDOListNew)) {
            for (DimensionSDO dimensionSDO : dimensionSDOListNew) {
                String valueName = dimensionSDO.getValueName();
                if (StringUtils.isNotBlank(valueName) && null != dimensionSDO.getId()) {
                    boolean contains = valueName.contains(":");
                    //如果是true 代表需要修改 否则不需要修改
                    if (contains) {
                        dimensionSDO.setStrategyId(id);
                        dimensionSDO.setValue(valueName.split(":")[1]);
                        dimensionSDO.setValueName(valueName.split(":")[0]);
                        dimensionWriteRepository.modify(dimensionSDO);
                    }
                }
                if (StringUtils.isNotBlank(valueName) && null == dimensionSDO.getId()) {
                    boolean contains = valueName.contains(":");
                    if (contains) {
                        dimensionSDO.setStrategyId(id);
                        dimensionSDO.setCode(code);
                        dimensionSDO.setValue(valueName.split(":")[1]);
                        dimensionSDO.setValueName(valueName.split(":")[0]);
                        for (DimensionSDO dimensionSDO1 : dimensionSDOListOld) {
                            if (dimensionSDO1.getValue().equals(dimensionSDO.getValue())) {
                                return false;
                            }
                        }
                        dimensionWriteRepository.create(dimensionSDO);
                    }
                }
            }
            dimensionSDOListNew.addAll(dimensionSDOListOld);
            List<DimensionSDO> dimensionSDOSFilter = dimensionSDOListNew.stream().filter(i -> i.getId() != null).collect(Collectors.toList());
            Map<Object, Long> map = dimensionSDOSFilter.stream().collect(
                    Collectors.groupingBy(DimensionSDO::getId, Collectors.counting()));
            List<Object> collect3 = map.keySet().stream().
                    filter(key -> map.get(key) > 1).collect(Collectors.toList());
            List<DimensionSDO> dimensionSDOS = dimensionSDOListOld.stream().filter(i ->
                    !collect3.contains(i.getId())
            ).collect(Collectors.toList());
            for (DimensionSDO dimensionSDO : dimensionSDOS) {
                if (null != dimensionSDO.getId()) {
                    dimensionSDO.setStrategyId(id);
                    dimensionWriteRepository.delete(dimensionSDO);
                }
            }
        }

        return true;
    }

    /**
     * 回复计算设定策略
     */
    @Override
    public Result<StrategyWriteCreateResponse> replyCalculationStrategy(StrategyWriteCreateRequest request){
        StrategyPageQueryRequest queryRequest = new StrategyPageQueryRequest();
        queryRequest.setOrganizationCode(request.getOrganizationCode());
        queryRequest.setType(request.getType());
        Result<List<StrategyPageQueryResponse>> listResult = strategyQueryRepository.pageQuery(queryRequest);
        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
            return Result.fail("999", "已存在相同适用组织无法创建");
        }
        return this.createStrategy(request);
    }


    /**
     * 创建起运量策略
     *
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<StrategyWriteCreateResponse> createRiseCarryAmount(CreateRiseCarryAmountRequest request) {
        if (StringUtils.isNotBlank(request.getId())) {
            DimensionPageQueryRequest dimensionPageQueryRequest = new DimensionPageQueryRequest();
            dimensionPageQueryRequest.setDimensionValue(request.getDimensionValue());
            dimensionPageQueryRequest.setStrategyId(request.getId());
            Result<List<DimensionPageQueryResponse>> listResult = dimensionQueryRepository.pageQuery(dimensionPageQueryRequest);
            if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                return Result.fail("999", "已存在相同维度不允许创建");
            }
        } else {
            StrategyPageQueryRequest queryRequest = new StrategyPageQueryRequest();
            queryRequest.setOrganizationCode(request.getOrganizationCode());
            queryRequest.setType(request.getType());
            Result<List<StrategyPageQueryResponse>> listResult = strategyQueryRepository.pageQuery(queryRequest);
            if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                return Result.fail("999", "已存在相同适用组织无法创建");
            }
        }
        StrategyWriteCreateRequest createRequest = new StrategyWriteCreateRequest();
        createRequest.setId(request.getId());
        createRequest.setDimensionValue(request.getDimensionValue());
        createRequest.setDimensionCode(request.getDimensionCode());
        createRequest.setName(request.getName());
        createRequest.setType(request.getType());
        createRequest.setOrganizationCode(request.getOrganizationCode());
        createRequest.setStrategyValid(request.getStrategyValid());
        createRequest.setRuleValue(request.getRuleValue());
        createRequest.setExecuteAction(request.getExecuteAction());
        createRequest.setValid(request.getValid());
        createRequest.setDimensionStatus(request.getDimensionStatus());
        return this.createStrategy(createRequest);
    }

    @Override
    @FacadeInvoker
    public Result<StrategyWriteCreateResponse> createValidCheck(StrategyWriteCreateRequest request) {

        if (RuleTypeEnum.TIME_FRAME.getCode().equals(request.getRule())){
            if (StringUtils.isBlank(request.getDailyBeginTime()) || StringUtils.isBlank(request.getDailyEndTime())) {
                return Result.fail("999", "截止时间和时间段不能同时为空");
            }
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
                if (sdf.parse(request.getDailyEndTime()).getTime() <= sdf.parse(request.getDailyBeginTime()).getTime()){
                    return Result.fail("999", "时间段的结束时间应大于开始时间");
                }
            } catch (ParseException e) {
                return Result.fail("999", "时间段的结束时间应大于开始时间");
            }
        }else if (RuleTypeEnum.TIME_POINT.getCode().equals(request.getRule())){
            if (StringUtils.isBlank(request.getRuleValue())) {
                return Result.fail("999", "截止时间和时间段不能同时为空");
            }
        }


        //主单id不为空
        if (StringUtils.isEmpty(request.getOrganizationCode())) {
            return Result.fail("999", "请选择组织");
        }
        if (StringUtils.isNotBlank(request.getId())) {
            DimensionPageQueryRequest dimensionPageQueryRequest = new DimensionPageQueryRequest();
            dimensionPageQueryRequest.setDimensionValue(request.getDimensionValue());
            dimensionPageQueryRequest.setStrategyId(request.getId());
            Result<List<DimensionPageQueryResponse>> listResult = dimensionQueryRepository.pageQuery(dimensionPageQueryRequest);
            if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                if (StringUtils.equals("1", request.getDimensionCode())) {
                    return Result.fail("999", "已存在相同维度不允许创建");
                } else {
                    return Result.fail("999", "已存在相同逻辑仓不允许创建");
                }

            }
        } else {
            StrategyPageQueryRequest queryRequest = new StrategyPageQueryRequest();
            queryRequest.setOrganizationCode(request.getOrganizationCode());
            queryRequest.setType(request.getType());
            queryRequest.setStatus(1);
            Result<List<StrategyPageQueryResponse>> listResult = strategyQueryRepository.pageQuery(queryRequest);
            if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                return Result.fail("999", "已存在相同适用组织无法创建");
            }
        }

        if (RuleTypeEnum.TIME_FRAME.getCode().equals(request.getRule())){
            request.setRuleValue(JSONObject.toJSONString(Lists.newArrayList(request.getDailyBeginTime(), request.getDailyEndTime())));
        }
        request.setDailyBeginTime(null);
        request.setDailyEndTime(null);
        return this.createStrategy(request);
    }

    /**
     * 优先回复策略
     *
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<StrategyWriteCreateResponse> createFirstReply(CreateFirstReplyRequest request) {
        if (StringUtils.isBlank(request.getOrganizationCode())) {
            return Result.fail("999", "请先选择组织后再保存");
        }
        if (StringUtils.isBlank(request.getName())) {
            return Result.fail("999", "请先填写策略名称后再保存");
        }
        if (CollectionUtils.isEmpty(request.getStrategyValid())) {
            return Result.fail("999", "请选择有效期范围后再保存");
        }
        if (StringUtils.isBlank(request.getId())) {
            StrategyPageQueryRequest queryRequest = new StrategyPageQueryRequest();
            queryRequest.setOrganizationCode(request.getOrganizationCode());
            queryRequest.setType(request.getType());
            queryRequest.setStatus(Integer.parseInt(StrategyStatusEnum.VALID.getCode()));
            Result<List<StrategyPageQueryResponse>> listResult = strategyQueryRepository.pageQuery(queryRequest);
            if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                return Result.fail("999", "已存在相同适用组织无法创建");
            }
        } else {
            StrategyQueryByIdRequest queryByIdRequest = new StrategyQueryByIdRequest();
            queryByIdRequest.setId(request.getId());
            queryByIdRequest.setCode(request.getDimensionCode());
            Result<StrategyQueryByIdResponse> result = strategyQueryRepository.queryById(queryByIdRequest);
            List<DimensionSDO> dimensionSDOList = result.getResult().getStrategySDO().getDimensionSDOList();

            if (CollectionUtils.isNotEmpty(dimensionSDOList)) {
                if (DimensionTypeEnum.CHANNEL.getCode().equals(request.getDimensionCode())) {
                    List<String> collect = request.getChannelList().stream().map(channel -> {
                        String[] split = channel.split(":");
                        return split[0];
                    }).collect(Collectors.toList());
                    for (DimensionSDO dimensionSDO : dimensionSDOList) {
                        if (collect.contains(dimensionSDO.getValueName())) {
                            return Result.fail("999", "不允许重复添加渠道，渠道名称：" + dimensionSDO.getValueName());
                        }
                    }
                }

                if (DimensionTypeEnum.DEPARTMENT.getCode().equals(request.getDimensionCode())) {
                    List<String> collect = request.getDepartmentList().stream().map(department -> {
                        String[] split = department.split(":");
                        return split[0];
                    }).collect(Collectors.toList());
                    for (DimensionSDO dimensionSDO : dimensionSDOList) {
                        if (collect.contains(dimensionSDO.getValueName())) {
                            return Result.fail("999", "不允许重复添加部门，部门名称：" + dimensionSDO.getValueName());
                        }
                    }
                }

                if (DimensionTypeEnum.CUSTOMER.getCode().equals(request.getDimensionCode())) {
                    List<String> collect = request.getCustomerList().stream().map(customer -> {
                        String[] split = customer.split(":");
                        return split[0];
                    }).collect(Collectors.toList());
                    for (DimensionSDO dimensionSDO : dimensionSDOList) {
                        if (collect.contains(dimensionSDO.getValueName())) {
                            return Result.fail("999", "不允许重复添加部门，部门名称：" + dimensionSDO.getValueName());
                        }
                    }
                }
            }
        }

        if (DimensionTypeEnum.CUSTOMER.getCode().equals(request.getDimensionCode())) {
            StrategyWriteCreateRequest createRequest = new StrategyWriteCreateRequest();
            createRequest.setId(request.getId());
            createRequest.setType(request.getType());
            createRequest.setOrganizationCode(request.getOrganizationCode());
            createRequest.setName(request.getName());
            createRequest.setStrategyValid(request.getStrategyValid());
            createRequest.setCustomerList(request.getCustomerList());
            createRequest.setDepartmentList(request.getDepartmentList());
            createRequest.setChannelList(request.getChannelList());
            createRequest.setDimensionCode(request.getDimensionCode());
            createRequest.setStatus(request.getStatus());
            return this.createStrategy(createRequest);
        }

        StrategySDO strategySDO = new StrategySDO();
        strategySDO.setId(request.getId());
        strategySDO.setType(request.getType());
        strategySDO.setStatus(request.getStatus());
        List<String> strategyValid = request.getStrategyValid();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            strategySDO.setValidBeginTime(simpleDateFormat.parse(strategyValid.get(0)));
            strategySDO.setValidEndTime(simpleDateFormat.parse(strategyValid.get(1)));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        strategySDO.setOrganizationCode(request.getOrganizationCode());
        strategySDO.setName(request.getName());

        List<DimensionSDO> dimensionSDOS = new ArrayList<>();
        //没id
        if (StringUtils.isBlank(request.getId())) {
            if (CollectionUtils.isNotEmpty(request.getChannelList())) {
                List<String> channelList = request.getChannelList();
                for (int i = 0; i < channelList.size(); i++) {
                    DimensionSDO dimensionSDO = new DimensionSDO();
                    String channel = channelList.get(i);
                    String[] channelSplit = channel.split(":");
                    dimensionSDO.setValue(channelSplit[1]);
                    dimensionSDO.setValueName(channelSplit[0]);
                    dimensionSDO.setStatus(request.getStatus());
                    dimensionSDO.setCode(request.getDimensionCode());
                    dimensionSDO.setPriority(i + 1);
                    dimensionSDOS.add(dimensionSDO);
                }
            }
            if (CollectionUtils.isNotEmpty(request.getDepartmentList())) {
                List<String> departmentList = request.getDepartmentList();
                for (int i = 0; i < departmentList.size(); i++) {
                    DimensionSDO dimensionSDO = new DimensionSDO();
                    String[] departmentSplit = departmentList.get(i).split(":");
                    dimensionSDO.setValue(departmentSplit[1]);
                    dimensionSDO.setValueName(departmentSplit[0]);
                    dimensionSDO.setStatus(request.getStatus());
                    dimensionSDO.setCode(request.getDimensionCode());
                    dimensionSDO.setPriority(i + 1);
                    dimensionSDOS.add(dimensionSDO);
                }
            }
        } else {
            if (DimensionTypeEnum.CHANNEL.getCode().equals(request.getDimensionCode())) {
                if (CollectionUtils.isNotEmpty(getDimensionList(request.getId(), DimensionTypeEnum.DEPARTMENT.getCode()))) {
                    return Result.fail("999", "该组织已添加部门，不允许添加渠道");
                }
                Result<List<Dimension>> listResult = getListResult(request);
                if (CollectionUtils.isEmpty(listResult.getResult())) {
                    List<String> channelList = request.getChannelList();
                    for (int i = 0; i < channelList.size(); i++) {
                        DimensionSDO dimensionSDO = new DimensionSDO();
                        String channel = channelList.get(i);
                        String[] channelSplit = channel.split(":");
                        dimensionSDO.setValue(channelSplit[1]);
                        dimensionSDO.setValueName(channelSplit[0]);
                        dimensionSDO.setStatus(request.getStatus());
                        dimensionSDO.setCode(request.getDimensionCode());
                        dimensionSDO.setPriority(i + 1);
                        dimensionSDOS.add(dimensionSDO);
                    }
                } else {
                    Integer priority = listResult.getResult().get(listResult.getResult().size() - 1).getPriority();
                    List<String> channelList = request.getChannelList();
                    for (int i = 0; i < channelList.size(); i++) {
                        DimensionSDO dimensionSDO = new DimensionSDO();
                        String channel = channelList.get(i);
                        String[] channelSplit = channel.split(":");
                        dimensionSDO.setValue(channelSplit[1]);
                        dimensionSDO.setValueName(channelSplit[0]);
                        dimensionSDO.setStatus(request.getStatus());
                        dimensionSDO.setCode(request.getDimensionCode());
                        dimensionSDO.setPriority(priority + 1);
                        dimensionSDOS.add(dimensionSDO);
                    }
                }
            }

            if (DimensionTypeEnum.DEPARTMENT.getCode().equals(request.getDimensionCode())) {
                if (CollectionUtils.isNotEmpty(getDimensionList(request.getId(), DimensionTypeEnum.CHANNEL.getCode()))) {
                    return Result.fail("999", "该组织已添加渠道，不允许添加部门");
                }
                Result<List<Dimension>> departmentResult = getListResult(request);
                if (CollectionUtils.isEmpty(departmentResult.getResult())) {
                    List<String> departmentList = request.getDepartmentList();
                    for (int i = 0; i < departmentList.size(); i++) {
                        DimensionSDO dimensionSDO = new DimensionSDO();
                        String[] departmentSplit = departmentList.get(i).split(":");
                        dimensionSDO.setValue(departmentSplit[1]);
                        dimensionSDO.setValueName(departmentSplit[0]);
                        dimensionSDO.setStatus(request.getStatus());
                        dimensionSDO.setCode(request.getDimensionCode());
                        dimensionSDO.setPriority(i + 1);
                        dimensionSDOS.add(dimensionSDO);
                    }
                } else {
                    Integer priority = departmentResult.getResult().get(departmentResult.getResult().size() - 1).getPriority();
                    int num = 1;
                    List<String> departmentList = request.getDepartmentList();
                    for (int i = 0; i < departmentList.size(); i++) {
                        DimensionSDO dimensionSDO = new DimensionSDO();
                        String channel = departmentList.get(i);
                        String[] channelSplit = channel.split(":");
                        dimensionSDO.setValue(channelSplit[1]);
                        dimensionSDO.setValueName(channelSplit[0]);
                        dimensionSDO.setStatus(request.getStatus());
                        dimensionSDO.setCode(request.getDimensionCode());
                        dimensionSDO.setPriority(priority + num++);
                        dimensionSDOS.add(dimensionSDO);
                    }
                }
            }

        }
        strategySDO.setDimensionSDOList(dimensionSDOS);
        StrategyEntity strategyEntity = StrategyFactory.createFirstReply(strategySDO);
        String id = strategyEntity.createFirstReply();
        StrategyWriteCreateResponse response = new StrategyWriteCreateResponse();
        response.setId(id);
        return Result.success(response);
    }

    private Result<List<Dimension>> getListResult(CreateFirstReplyRequest request) {
        QueryListByPriorityRequest queryListByPriorityRequest = new QueryListByPriorityRequest();
        queryListByPriorityRequest.setStrategyId(request.getId());
        queryListByPriorityRequest.setCode(request.getDimensionCode());
        Result<List<Dimension>> listResult = dimensionQueryRepository.queryListByPriority(queryListByPriorityRequest);
        return listResult;
    }

    /**
     * 创建每日库存分配策略
     *
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<StrategyWriteCreateResponse> createDailyInventory(CreateDailyInventoryRequest request) {
        if (StringUtils.isBlank(request.getOrganizationCode())) {
            return Result.fail("999", "适用组织不能为空");
        }
        if (StringUtils.isBlank(request.getName())) {
            return Result.fail("999", "策略名称不能为空");
        }
        if (CollectionUtils.isEmpty(request.getStrategyValid())) {
            return Result.fail("999", "策略生效起止时间不能为空");
        }
        if (StringUtils.isBlank(request.getDailyBeginTime())) {
            return Result.fail("999", "每日生效开始时间为空");
        }
        if (StringUtils.isBlank(request.getDailyEndTime())) {
            return Result.fail("999", "每日生效结束时间为空");
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
        try {
            Long begin = simpleDateFormat.parse(request.getDailyBeginTime()).getTime();
            Long end = simpleDateFormat.parse(request.getDailyEndTime()).getTime();
            if (begin >= end) {
                return Result.fail("999", "每日生效开始时间不得大于每日生效结束时间");
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        List<String> ids = strategyQueryRepository.checkStrategy(request);
        //判断相同的是否存在
        if (CollectionUtils.isNotEmpty(ids)) {
            for (String id : ids) {
                //判断是否存在相同货品
                if (CollectionUtils.isNotEmpty(request.getScItemList())) {
                    for (String scItem : request.getScItemList()) {
                        //查询维度
                        DimensionPageQueryRequest queryRequest = new DimensionPageQueryRequest();
                        queryRequest.setStrategyId(id);
                        queryRequest.setDimensionValue(scItem.split(":")[1]);
                        Result<List<DimensionPageQueryResponse>> listResult = dimensionQueryRepository.pageQuery(queryRequest);
                        //不为空说明有相同货品直接抛出
                        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                            return Result.fail("999", "不允许重复创建货品分配范围,货品名称:" + scItem.split(":")[0]);
                        }
                    }
                }

                //判断是否存在相同逻辑仓
                if (CollectionUtils.isNotEmpty(request.getWarehouseList())) {
                    for (String warehouse : request.getWarehouseList()) {
                        //查询维度
                        DimensionPageQueryRequest queryRequest = new DimensionPageQueryRequest();
                        queryRequest.setStrategyId(id);
                        queryRequest.setDimensionValue(warehouse.split(":")[1]);
                        Result<List<DimensionPageQueryResponse>> listResult = dimensionQueryRepository.pageQuery(queryRequest);
                        //不为空说明有相同逻辑仓直接抛出
                        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                            return Result.fail("999", "不允许创建重复逻辑仓分配范围,逻辑仓名称:" + warehouse.split(":")[0]);
                        }
                    }
                }

                //判断是否存在相同渠道维度
                if (CollectionUtils.isNotEmpty(request.getChannelList())) {
                    for (String channel : request.getChannelList()) {
                        //查询维度
                        DimensionPageQueryRequest queryRequest = new DimensionPageQueryRequest();
                        queryRequest.setStrategyId(id);
                        queryRequest.setDimensionValue(channel.split(":")[1]);
                        Result<List<DimensionPageQueryResponse>> listResult = dimensionQueryRepository.pageQuery(queryRequest);
                        //不为空说明有相同维度直接抛出
                        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                            return Result.fail("999", "不允许重复创建逻辑仓分配范围,维度名称:" + channel.split(":")[0]);
                        }
                    }
                }

                //判断是否存在相同部门维度
                if (CollectionUtils.isNotEmpty(request.getDepartmentList())) {
                    for (String department : request.getDepartmentList()) {
                        //查询维度
                        DimensionPageQueryRequest queryRequest = new DimensionPageQueryRequest();
                        queryRequest.setStrategyId(id);
                        queryRequest.setDimensionValue(department.split(":")[1]);
                        Result<List<DimensionPageQueryResponse>> listResult = dimensionQueryRepository.pageQuery(queryRequest);
                        //不为空说明有相同维度直接抛出
                        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                            return Result.fail("999", "不允许重复创建维度分配范围,维度名称:" + department.split(":")[0]);
                        }
                    }
                }

                //业务员
                if (CollectionUtils.isNotEmpty(request.getSalesmanList())) {
                    for (String salesman : request.getSalesmanList()) {
                        //查询维度
                        DimensionPageQueryRequest queryRequest = new DimensionPageQueryRequest();
                        queryRequest.setStrategyId(id);
                        queryRequest.setDimensionValue(salesman.split(":")[1]);
                        Result<List<DimensionPageQueryResponse>> listResult = dimensionQueryRepository.pageQuery(queryRequest);
                        //不为空说明有相同维度直接抛出
                        if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                            return Result.fail("999", "不允许重复创建维度分配范围,维度名称:" + salesman.split(":")[0]);
                        }
                    }
                }
            }
        }
        StrategyWriteCreateRequest createRequest = new StrategyWriteCreateRequest();
        createRequest.setId(request.getId());
        createRequest.setType(request.getType());
        if (StringUtils.isBlank(request.getId())) {
            createRequest.setStatus(request.getStatus());
        } else {
            createRequest.setStatus(StrategyStatusEnum.VALID.getCode());
        }

        createRequest.setOrganizationCode(request.getOrganizationCode());
        createRequest.setName(request.getName());
        createRequest.setDailyBeginTime(request.getDailyBeginTime());
        createRequest.setDailyEndTime(request.getDailyEndTime());
        createRequest.setStrategyValid(request.getStrategyValid());
        createRequest.setDimensionType(request.getDimensionType());
        createRequest.setPriority(request.getPriority());
        createRequest.setShare(request.getShare());
        createRequest.setChannelList(request.getChannelList());
        createRequest.setDepartmentList(request.getDepartmentList());
        createRequest.setSalesmanList(request.getSalesmanList());
        createRequest.setWarehouseList(request.getWarehouseList());
        createRequest.setScItemList(request.getScItemList());
        createRequest.setDimensionCode(request.getDimensionCode());
        return this.createStrategy(createRequest);
    }

    @Override
    @FacadeInvoker
    public Result<StrategyWriteDeleteResponse> deleteStrategy(StrategyWriteDeleteRequest request) {
        StrategyEntity strategyEntity = StrategyFactory.deleteStrategy(request);
        StrategyWriteDeleteResponse response = new StrategyWriteDeleteResponse();
        String id = strategyEntity.delete();
        response.setId(id);
        return Result.success(response);
    }

    @Override
    @FacadeInvoker
    public Result<StrategyWriteUpdateResponse> updateStrategy(StrategyWriteUpdateRequest request) {
        StrategyEntity strategyEntity = StrategyFactory.updateStrategy(request);
        String id = strategyEntity.modify();
        StrategyWriteUpdateResponse response = new StrategyWriteUpdateResponse();
        response.setId(id);
        return Result.success(response);
    }

    @Override
    @FacadeInvoker
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public Result<StrategyWriteUpdateResponse> updateStrategyAndDimension(StrategyWriteCreateRequest request) {

        if(RuleTypeEnum.TIME_POINT.getCode().equals(request.getRule())){
            if (StringUtils.isBlank(request.getRuleValue())){
                return Result.fail("999", "截止时间和时间段不能同时为空");
            }
        }else if (RuleTypeEnum.TIME_FRAME.getCode().equals(request.getRule())){
            if (StringUtils.isBlank(request.getRuleValue())){
                return Result.fail("999", "截止时间和时间段不能同时为空");
            }
            List<String> ruleValues = JSONObject.parseArray(request.getRuleValue(), String.class);
            if (ruleValues.size() != 2 || StringUtils.isBlank(ruleValues.get(0)) || StringUtils.isBlank(ruleValues.get(1))){
                return Result.fail("999", "截止时间和时间段不能同时为空");
            }

            try {
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
                if (sdf.parse(ruleValues.get(1)).getTime() <= sdf.parse(ruleValues.get(0)).getTime()){
                    return Result.fail("999", "时间段的结束时间应大于开始时间");
                }
            } catch (ParseException e) {
                return Result.fail("999", "时间段的结束时间应大于开始时间");
            }
        }


        StrategySDO strategySDO = null;
        try {
            strategySDO = ConverterUtils.strategyWriteUpdateRequestConverter(request);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String id = strategyWriteRepository.edit(strategySDO);

        DimensionWriteUpdateRequest updateDimensionRequest = null;
        try {
            updateDimensionRequest = ConverterUtils.dimensionWriteUpdateRequestConverter(request);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        dimensionWriteService.updateDimension(updateDimensionRequest);
        StrategyWriteUpdateResponse strategyWriteUpdateResponse = new StrategyWriteUpdateResponse();
        strategyWriteUpdateResponse.setId(id);
        return Result.success(strategyWriteUpdateResponse);
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> saveStrategy(SaveStrategyRequest saveStrategyRequest) {
        if (StrategyTypeEnum.DAILY_INVENTORY.getCode().equals(saveStrategyRequest.getType())) {


            if (StringUtils.isBlank(saveStrategyRequest.getId())) {
                return Result.fail("999", "未添加维度分配范围和逻辑仓分配范围不允许保存");
            }
            StrategyQueryByIdRequest request = new StrategyQueryByIdRequest();
            request.setId(saveStrategyRequest.getId());
            Result<StrategyQueryByIdResponse> result = strategyQueryRepository.queryById(request);
            if (CollectionUtils.isEmpty(result.getResult().getStrategySDO().getDimensionSDOList())) {
                Result.fail("999", "请添加维度分配范围和逻辑仓分配范围后再保存");
            }
            List<String> codeList = new ArrayList<>();
            for (DimensionSDO dimensionSDO : result.getResult().getStrategySDO().getDimensionSDOList()) {
                codeList.add(dimensionSDO.getCode());
            }
            if (!codeList.contains(result.getResult().getStrategySDO().getDimensionType())) {
                return Result.fail("999", "请添加维度分配范围后再保存");
            }
            if (!codeList.contains(DimensionTypeEnum.STORE_ROOM.getCode())) {
                return Result.fail("999", "请添加逻辑仓库分配范围后再保存");
            }
        }
        StrategyEntity strategyEntity = StrategyFactory.saveStrategy(saveStrategyRequest);
        strategyEntity.save();
        return Result.success(true);
    }

    @Override
    @FacadeInvoker
    public Result<FbGenerateOrderSwitchReponse> createGenerateOrderSwitch(FbGenerateOrderSwitchRequest fbGenerateOrderSwitchRequest) {
        //校验重复，组织+策略类型 只允许存在一个
        if (fbGenerateOrderSwitchRequest.getId() == null) {
            StrategyPageQueryRequest request = new StrategyPageQueryRequest();
            request.setType(fbGenerateOrderSwitchRequest.getType());
            request.setOrganizationCode(fbGenerateOrderSwitchRequest.getOrgCode());
            request.setStatus(1);
            Result<List<StrategyPageQueryResponse>> listResult = strategyQueryRepository.pageQuery(request);
            if (CollectionUtils.isNotEmpty(listResult.getResult())) {
                throw new FacadeException("OTS-04-001-00-15-024");
            }
        }

        StrategyEntity strategyEntity = StrategyFactory.bulid(fbGenerateOrderSwitchRequest);
        String id = strategyEntity.createAndUpdate();
        FbGenerateOrderSwitchReponse response = new FbGenerateOrderSwitchReponse();
        response.setId(id);
        return Result.success(response);
    }

    public List<DimensionSDO> getDimensionList(String id, String dimensionCode) {
        StrategyQueryByIdRequest queryByIdRequest = new StrategyQueryByIdRequest();
        queryByIdRequest.setId(id);
        queryByIdRequest.setCode(dimensionCode);
        Result<StrategyQueryByIdResponse> result = strategyQueryRepository.queryById(queryByIdRequest);
        return result.getResult().getStrategySDO().getDimensionSDOList();
    }
}
